[Thymeleaf] 검증오류 (th:errors, th:errorclass)

Thymeleaf에서 폼 검증 오류를 표시하는 th:errors, th:errorclass를 정리한 노트다. #fields.hasErrors('속성')으로 오류 유무를 확인해 th:errors가 메시지를 출력하고, th:errorclass는 오류 시 적용할 CSS 클래스를 지정하며 보통 둘을 함께 쓴다. 이 기능은 서버 쪽 Spring BindingResult가 채워주는 필드 오류 정보에 의존하므로, 컨트롤러의 검증 로직 작성이 함께 중요하다.

실행 환경

Controller 예제에서 @PostMapping, @ModelAttribute, BindingResult, Lombok @Data가 사용되고 있어 Spring MVC(4.3+, @PostMapping 도입 버전 이상) + thymeleaf-spring 연동 환경을 전제로 한다. 구체적인 Spring/Thymeleaf 버전은 명시되어 있지 않다.

th:errors

  • 모델의 속성이 유효성 검사를 통과하지 못했을경우, html에 표현됨
  • fields.hasErrors(‘속성’) 을 이용해서, 유효성 검사의 유무를 파악 (오류가 있을경우, fields에 지정해둔 msg가 출력 )
  • 주로, 오류 메시지를 표시하는 역할
<head>
<!-- ... -->
 
<style>
 .field-error{
      color : red;
 }   
</style>
</head>
<body>
 
<form th:action="@{/validation}" th:object="${user}" method="post">
    <label for="username"> 이름 </label>
    <input type="text" th:field="*{username}" />
    <span class="field-error" th:if=${#fields.hasErrors('username')}" th:errors="*{username}"></span>
</form>
 
</body>

th:errorclass

  • 유효성 검사 오류시, css 를 적용시키기 위한 속성값
  • 주로, 시각적으로 오류가 나타남을 표시하는 역할
  • th:errors 와 th:errorclass는 같이 사용되는 경우가 많다
<!-- form.html -->
 
<head>
<!-- ... -->
 
<style>
 .field-error{
      color : red;
 }   
</style>
</head>
<body>
 
<form th:action="@{/validation}" th:object="${user}" method="post">
    <label for="username"> 이름 </label>
    <input type="text" th:field="*{username}" th:errorclass="field-error" class="form-control" />
    <span class="field-error" th:if=${#fields.hasErrors('username')}" th:errors="*{username}"></span>
</form>
 
</body>

검증의 경우,

spring과 연계되어 작업되는 경우가 많으므로, spring controller의 작성도 중요시여기게 된다
fields와 같은 역할도 결국, 서버에서 지정해줘야한다. (BindingResult)

// Controller
 
@PostMapping("/validation")
public String validate(@ModelAttribute("user") User user, BindingResult bindingResult){
     if (user.getUsername() == null || user.getUsername().isEmpty()){
         bindingResult.rejectValue("username", "error.username", "이름은 필수입니다");
     }
     
     if (bindingResult.hasErrors()) {
            return "form"; // 폼 뷰를 다시 렌더링
        }
     
     return "redirect:/home";
     
}
 
@GetMapping("/form")
public String form(){
   return "form";
}
 
@Data
public static class User{
    private String username;
}